package com.jobcn.service;

import com.jobcn.common.util.IpAddressTool;
import com.jobcn.dic.SpiderDic;
import com.jobcn.entity.*;
import com.jobcn.repository.bizopp.MerBizInfoRepository;
import com.jobcn.repository.bizopp.MerCertificateRepository;
import com.jobcn.repository.bizopp.MerInfoRepository;
import com.jobcn.repository.spider.SpiderInfoRepository;
import com.jobcn.repository.spider.SpiderMerRepository;
import com.jobcn.repository.spider.SpiderTaskRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by winson on 17-7-5.
 */
@Service("bizoppService")
public class BizoppServiceImpl implements BizoppService {
    final static Logger logger = LoggerFactory.getLogger(BizoppServiceImpl.class);
    final static int SOURCE_REGISTER = 0;
    final static int SOURCE_IMPORT = 1;
    @Autowired
    SpiderMerRepository SpiderMerRepository;
    @Autowired
    SpiderInfoRepository spiderInfoRepository;
    @Autowired
    MerInfoRepository merInfoRepository;
    @Autowired
    MerBizInfoRepository merBizInfoRepository;
    @Autowired
    MerCertificateRepository merCertificateRepository;
    @Autowired
    SpiderTaskRepository spiderTaskRepository;

    @Override
    public Map update58ToBizopp(SpiderTask spiderTask) {
        List<SpiderMer> merList = SpiderMerRepository.findAllByMerSource(SpiderDic.SPIDER_SOURCE_58);
        int merTotal = 0;
        int infoTotal = 0;
        for (SpiderMer mer : merList) {

            //==============检查是否已经存在的注册来源的该商家,有则不更新了==============
            if (mer.getCompanyName() != null && merCertificateRepository.countByName(mer.getCompanyName()) > 0) {
                continue;
            }
            //==============如果这个商家已经转为注册用户,则不更新了==============
            if (merInfoRepository.countBySourceIdAndSource(mer.getMerId(), SOURCE_REGISTER) > 0) {
                continue;
            }
            //==============如果没有认证信息,则不更新了==============
            if (mer.getCompanyName() == null
                    || mer.getCreditCode() == null
                    || "".equals(mer.getCompanyName().toLowerCase()) ||
                    "".equals(mer.getCreditCode().toLowerCase())) {
                continue;
            }

            MerInfo merInfo = new MerInfo(
                    mer.getMerName(), mer.getCreditCode(),
                    null, mer.getMerDescription(),
                    null, null, null,
                    mer.getPhone(), null, null, null, null,
                    mer.getAddress(), mer.getLongitude(), mer.getLatitude(),
                    false, 2, null, new Date(), null,
                    IpAddressTool.ipToLong("0.0.0.0"),
                    new Date(), new Date(), SOURCE_IMPORT, mer.getMerId());

            //==============检查商库网是否已经存在该商家==============
            MerInfo merInfoOrigin = merInfoRepository.findBySourceIdAndSource(mer.getMerId(), SOURCE_IMPORT);
            //==============如果这个商家已经被禁用了则不更新==============
            if (merInfoOrigin != null) {
                merInfo.setMerId(merInfoOrigin.getMerId());
                if (merInfoOrigin.getDisable())
                    continue;
            }

            //==============否则新增商家,这里不添加linkman,到最后添加==============
            String linkMan = null;
            merInfoOrigin = merInfoRepository.save(merInfo);

            //==============获取该商家的所有线上的信息==============
            List<MerBizInfo> merBizInfoOriginList = null;
            List<MerBizInfo> merBizInfoDisableOriginList = null;
            if (merInfoOrigin != null) {
                merInfo.setMerId(merInfoOrigin.getMerId());
                merBizInfoOriginList = merBizInfoRepository.findByMerIdAndInfoStateAndSource(merInfoOrigin.getMerId(), 2, SOURCE_IMPORT);
                merBizInfoDisableOriginList = merBizInfoRepository.findByMerIdAndInfoStateAndSource(merInfoOrigin.getMerId(), 0, SOURCE_IMPORT);
            }

            //====================获取该商家的爬下来的所有信息====================
            List<SpiderInfo> infoList = spiderInfoRepository.findByMerIdOrderByUpdateTimeDesc(mer.getMerId());
            //更新联系人
            for (SpiderInfo spiderInfo : infoList) {
                if (linkMan != null)
                    break;
                if (linkMan == null && spiderInfo.getLinkName() != null && !"".equals(spiderInfo.getLinkName()))
                    linkMan = spiderInfo.getLinkName();
            }
            //需要更新的数据
            List<SpiderInfo> infoOldList = new ArrayList<>();
            //需要新增加的数据
            List<SpiderInfo> infoNewList = new ArrayList<>();
            //需要更新的条数
            int count = 20;
            //用来去除重名的map
            Map nameMap = new HashMap();
            Map nameDisableMap = new HashMap();
            //用来判断数据库中是否已经存在该条信息
            Map sourceMap = new HashMap();
            if (merBizInfoOriginList != null) {
                count = count - merBizInfoOriginList.size();
                for (MerBizInfo merBizInfo : merBizInfoOriginList) {
                    nameMap.put(merBizInfo.getInfoName(), merBizInfo);
                    sourceMap.put(merBizInfo.getSourceId(), merBizInfo);
                }
            }
            if (merBizInfoDisableOriginList != null) {
                for (MerBizInfo merBizInfo : merBizInfoDisableOriginList) {
                    nameDisableMap.put(merBizInfo.getInfoName(), merBizInfo);
                }
            }
            //这是需要新增的信息,如果原来已经有15条可用，这里只会有5条，如果原来有20条或以上，则这里就没。
            for (SpiderInfo info : infoList) {
                if (sourceMap.containsKey(info.getInfoId())) {
                    infoOldList.add(info);
                }
                if (count > 0) {
                    if (!nameMap.containsKey(info.getInfoName())) {
                        if (!nameDisableMap.containsKey(info.getInfoName())) {
                            nameMap.put(info.getInfoName(), info);
                            infoNewList.add(info);
                            count--;
                        }
                    }
                }
            }

            //SpiderInfo 转 MerBizInfo
            //需要更新的数据
            List<MerBizInfo> merBizInfoOldList = spiderInfo2MerBizInfo(merInfoOrigin, mer, infoOldList);
            //添加原id
            for (MerBizInfo merBizInfo : merBizInfoOldList) {
                if (nameMap.containsKey(merBizInfo.getInfoName())) {
                    //信息的发布时间不同才更新
                    merBizInfo.setInfoId(((MerBizInfo) nameMap.get(merBizInfo.getInfoName())).getInfoId());
                    if (((MerBizInfo) nameMap.get(merBizInfo.getInfoName())).getPostTime() != null) {
                        merBizInfo.setPostTime(((MerBizInfo) nameMap.get(merBizInfo.getInfoName())).getPostTime());
                    }
                    merBizInfo.setRegisterTime(((MerBizInfo) nameMap.get(merBizInfo.getInfoName())).getRegisterTime());
                    merBizInfoRepository.save(merBizInfo);
                }
            }
            //需要新增加的数据
            List<MerBizInfo> merBizInfoNewList = spiderInfo2MerBizInfo(merInfoOrigin, mer, infoNewList);
            for (MerBizInfo merBizInfo : merBizInfoNewList) {
                merBizInfoRepository.save(merBizInfo);
            }

            logger.info("商家：{},服务信息：{}条,更新:{}条,新增:{}条", mer.getMerId(), infoList.size(), merBizInfoOldList.size(), merBizInfoNewList.size());
            //更新MerInfo的联系人
            merInfoOrigin.setLinkMan(linkMan);
            merInfoRepository.save(merInfoOrigin);

            //插入证照
            //检查是否已经存在该商家的证照
            MerCertificate merCert = merCertificateRepository.findByMerid(merInfoOrigin.getMerId());
            if (merCert == null)
                merCert = new MerCertificate();
            merCert.setCertcode(mer.getCreditCode());
            merCert.setMerid(merInfoOrigin.getMerId());
            merCert.setCheckflag(new Long(0));
            merCert.setCerttype(new Long(1));
            merCert.setName(mer.getCompanyName());
            merCert.setUpdatetime(new Date());
            merCert.setAddress(mer.getAddress());
            merCert.setRegistertime(new Date());
            merCertificateRepository.save(merCert);

            //更新数量
            merTotal++;
            infoTotal = infoTotal + merBizInfoOldList.size() + merBizInfoNewList.size();
            //不是每次都更新,这里设置没10个商家更新一次
            if (merTotal % 10 == 0) {
                spiderTask.setUpdateDatetime(new Date());
                spiderTask.setMerCount(new Long(merTotal));
                spiderTask.setInfoCount(new Long(infoTotal));
                spiderTask = spiderTaskRepository.save(spiderTask);
            }
        }
        //完成更新
        logger.info("完成更新任务：{}", spiderTask.getId());
        spiderTask.setEndDatetime(new Date());
        spiderTask.setStatus(SpiderDic.STATUS_FINISH);
        spiderTask.setUpdateDatetime(new Date());
        spiderTask.setMerCount(new Long(merTotal));
        spiderTask.setInfoCount(new Long(infoTotal));
        spiderTask.setMsg("更新完毕");
        spiderTaskRepository.save(spiderTask);
        return null;

    }

    //SpiderInfo 转 MerBizInfo
    private List<MerBizInfo> spiderInfo2MerBizInfo(MerInfo merInfoOrigin, SpiderMer mer, List<SpiderInfo> infoList) {
        List<MerBizInfo> merBizInfoList = new ArrayList<>();
        for (SpiderInfo info : infoList) {
            if (info.getAddress() == null) {
                continue;
            }
            String[] addressArr = info.getAddress().split(";");
            String address = addressArr[addressArr.length - 1];
            MerBizInfo merBizInfo = new MerBizInfo(
                    merInfoOrigin.getMerId(),
                    info.getInfoName(),
                    0,
                    0,
                    0, 0, 0, 0, 0,
                    info.getInfoDescription(), info.getInfoPrice(), info.getInfoClass(), info.getLinkName(),
                    null, null, mer.getPhone(), null, null, null
                    , info.getAddressCode(), address, mer.getLongitude().toString(), mer.getLatitude().toString(),
                    2, info.getInfoUpdateTime(), 0, null, 2,
                    null, new Date(), null, info.getInfoUpdateTime(), new Date(),
                    SOURCE_IMPORT, info.getInfoId()
            );
            //解析服务地区地区
            Integer[] areaCode = convertServiceArea2Code(info.getAddressCode(), info.getServiceArea());
            if (areaCode.length > 0) {
                for (int i = 0; i < areaCode.length; i++) {
                    switch (i) {
                        case 0:
                            if (areaCode[i] == null) {
                                merBizInfo.setServLoc1(Integer.parseInt(info.getAddressCode()));
                            } else {
                                merBizInfo.setServLoc1(areaCode[i]);
                            }
                            break;
                        case 1:
                            merBizInfo.setServLoc2(areaCode[i]);
                            break;
                        case 2:
                            merBizInfo.setServLoc3(areaCode[i]);
                            break;
                        case 3:
                            merBizInfo.setServLoc4(areaCode[i]);
                            break;
                        case 4:
                            merBizInfo.setServLoc5(areaCode[i]);
                            break;
                        default:
                            break;
                    }
                }
            }
            merBizInfoList.add(merBizInfo);
        }
        return merBizInfoList;
    }


    /**
     * 解析服务地区
     *
     * @param code        市级别的code 例如东莞 3002
     * @param serviceArea 爬下来的服务区域： 东莞周边;莞城;南城;东城;万江;寮步;大朗;常平;黄江;松山湖;
     * @return
     */
    private Integer[] convertServiceArea2Code(String code, String serviceArea) {
        List<Integer> list = new ArrayList<>();
        String[] addresses = serviceArea.split(";");
        Map<String, String> map = SpiderDic.ADDRESS_CODE.get(code);
        for (int i = 0; i < addresses.length; i++) {
            k1:
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (entry.getValue().contains(addresses[i])) {
                    list.add(Integer.parseInt(entry.getKey()));
                    break k1;
                }
            }
        }
        return list.toArray(new Integer[]{list.size()});
    }

}
